﻿using System;
using System.Globalization;
using System.IO;
using System.Xml.Serialization;
using System.Collections;
namespace SharePoint.ImportExport.Core 
{
    
    
    
    /// <summary>
    /// This is the main class for importing the list or library data. There has to be exactly one instance of this class for each items.xml file
    /// </summary>
    /// <remarks>
    /// Each items file can contain multiple profile instances
    /// </remarks>
    /// <example>
    /// <code>
		/// //Create a new instance of the list class
		/// SharePoint.ImportExport.Core.List list=new List();
		/// 
		/// //Add a new profile node (the profile node indicates to which list/library the data will be imported
		/// Profile profile=new Profile();
		/// list.Profiles.Add(profile);
		/// profile.Name="My Document Library";
		/// 
		/// Item item= new Item();
		/// profile.Items.Add(item);
		/// item.Displayname="My word document.doc";
		/// item.Filename="myworddoc.doc"; //This can also be an absolute or UNC path
		/// 
		/// Itemfield itemField= new Itemfield();
		/// itemField.Name="MyField";
		/// itemField.Type=FieldType.Text;
		/// itemField.Value="My data";
		/// item.Fields.Add(itemField);
		/// 
		/// //Create a new alert
		/// Alert alert= new Alert();
		/// alert.Frequency="Daily";
		/// alert.User="DOMAIN\\user";
		/// alert.Type="Modify";
		/// item.Alerts.Alert.Add(alert);
		/// 
		/// //Create a new portal listing
		/// Categories portalListings=new Categories();
		/// portalListings.Value="//Topics/strategy"; //This are will get the listing
		/// item.Categories.Add(portalListings);
		/// 
		/// try
		///		{
		///			list.Serialize("items.xml");
		///		}
		///	catch(SPExportException ex)
		///		{
		///			Console.WriteLine("Exception occurred: "+ex.Message);
		///		}
    /// </code></example>

    [System.Xml.Serialization.XmlRootAttribute("list",Namespace="", IsNullable=false)]
    public class List {
			/// <summary>
			/// Default constructor for the List class
			/// </summary>
			/// <remarks>
			/// The constructor instantiates the Profile member</remarks>
			public List()
			{
				profiles=new ProfilesCollection();
			}
        
        private ProfilesCollection profiles;
			/// <summary>
			/// This is the profile <see cref="SharePoint.ImportExport.Core.ProfilesCollection"/> array that contains the information to which lists/libraries the content will be imported
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("profile", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public ProfilesCollection Profiles
			{
				get
				{
					return profiles;

				}
			}

			private void ValidateField(Itemfield field)
			{
				if(field.Name==null)
					throw new SPExportException("A field must have a name defined");
				if(field.Value==null)
					throw new SPExportException("A field must have the value defined");
			}
			private void ValidateItem(Item item)
			{
				if(item.Fields==null && item.Displayname==null && item.Filename ==null)
					throw new SPExportException("A item node must have a either the field nodes or (displayname and filename defined)");
				if(item.Displayname!=null && item.Filename ==null)
					throw new SPExportException("A item node must have both (displayname and filename defined)");
				if(item.Displayname==null && item.Filename !=null)
					throw new SPExportException("A item node must have both (displayname and filename defined)");
				if(item.Fields!=null)
				{
					int i=0;
					foreach(Itemfield field in item.Fields)
					{
						if(field != null)
						{
							try
							{
								ValidateField(field);
							}
							catch(SPExportException ex)
							{

								throw new SPExportException("Field "+i.ToString(CultureInfo.InvariantCulture)+ "validation failed. Error: "+ex.Message);
							}
							i++;
						}
					}
				}
			}


			private void ValidateProfile(Profile profile)
			{
				if(profile.Name==null)
					throw new SPExportException("A Profile node must have a name");
				if(profile.Items!=null)
				{
					foreach(Item item in profile.Items)
					{
						if(item != null)
						{
							try
							{
								ValidateItem(item);
							}
							catch(SPExportException ex)
							{

								throw new SPExportException("Field validation in Profile "+profile.Name + "failed. Error: "+ex.Message);
							}
						}
					}
				}
			}

			/// <summary>
			/// This is the serialization function for the items class
			/// </summary>
			/// <param name="fileName">this is the name of the XML file that will be generated</param>
			/// <returns></returns>
			/// <remarks>The method will throw as SPExportException if the data is invalid</remarks>
			public bool Serialize(string fileName)
			{

				string dirName=fileName;
				int pos=dirName.LastIndexOf("\\");
				if(pos>0)
					dirName=dirName.Substring(0,pos);

				if(pos!=-1) //Create the file in the working directory
				{
					if (!Directory.Exists(dirName))
						Directory.CreateDirectory(dirName);
				}


				bool returnValue=true;
				if(this.Profiles==null)
				{
					throw new SPExportException("The items.xml should contain at least one Profile node");
				}
				foreach(Profile profile in this.Profiles)
				{
					if(profile!=null)
					{
						try
						{
							ValidateProfile(profile);
						}
						catch(SPExportException ex)
						{
							throw ex;
						}
					}
				}
				
				StreamWriter exportItemsFile = new StreamWriter(fileName,false);
				try
				{
					XmlSerializer mySerializer = new XmlSerializer(typeof(SharePoint.ImportExport.Core.List));
					mySerializer.Serialize(exportItemsFile , this);
				}
				catch(Exception exSerialize)
				{
					Console.WriteLine("Exception error: "+exSerialize.Message);
					SPExportException ex= new SPExportException(exSerialize.Message);
					throw ex;
				}
				finally
				{
					exportItemsFile .Flush();
					exportItemsFile .Close();
				}
				return returnValue;

			}
		
    }
	/// <summary>
	/// This is the class implementing the Profiles collection. This class contains  <see cref="SharePoint.ImportExport.Core.Profile"/> nodes
	/// </summary>
	/// <remarks>
	/// <seealso cref="SharePoint.ImportExport.Core.Profile"/><seealso cref="SharePoint.ImportExport.Core.List"/>
	/// </remarks>
	public class ProfilesCollection:ICollection
	{
		/// <summary>
		/// Default constructor for the ProfilesCollection class. 
		/// </summary>
		/// <remarks>
		/// The constructor instantiates the profilesCollection member</remarks>

		public ProfilesCollection()
		{
			profilesCollection=new ArrayList();
		}
		private ArrayList profilesCollection;
		#region ICollection Members

		/// <summary>
		/// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
		/// </summary>
		/// <remarks>
		/// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
		/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
		/// </remarks>
		public bool IsSynchronized
		{
			get
			{
				
				return profilesCollection.IsSynchronized;
			}
		}

		/// <summary>
		/// Returns a value indicating the number of objects in the collection. Read-only.
		/// </summary>
		public int Count
		{
			get
			{
				return profilesCollection.Count;
			}
		}
		/// <summary>
		/// Copies the entire Profile Array to a compatible one-dimensional Array, starting at the specified index of the target array.
		/// </summary>
		/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
		/// <param name="index">The zero-based index in array at which copying begins</param>
		public void CopyTo(Profile[] a, int index)
		{
			profilesCollection.CopyTo(a, index);
		}


		/// <summary>
		/// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
		/// </summary>
		/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
		/// <param name="index">The zero-based index in array at which copying begins</param>
		public void CopyTo(Array a, int index)
		{
			profilesCollection.CopyTo(a, index);
		}


		/// <summary>
		/// Gets an object that can be used to synchronize access to the ArrayList.
		/// </summary>
		/// <remarks>
		/// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
		/// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
		/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
		/// catch the exceptions resulting from changes made by other threads.
		/// </remarks>
		public object SyncRoot
		{
			get
			{
				return profilesCollection.SyncRoot;
			}
		}

		#endregion

		#region IEnumerable Members

		/// <summary>
		/// Returns an enumerator that can iterate through the ArrayList.
		/// </summary>
		/// <returns></returns>
		public IEnumerator GetEnumerator()
		{
			return profilesCollection.GetEnumerator() ;
		}

		#endregion
		/// <summary>
		/// Gets the element at the specified index.
		/// </summary>
		public Profile this[int index]
		{
			get{return (Profile) profilesCollection[index];}
		}
		/// <summary>
		/// Adds an object to the end of the ArrayList.
		/// </summary>
		/// <param name="newProfile">New Profile to be added to the list</param>
		public void Add(Profile  newProfile)
		{
			profilesCollection.Add(newProfile);
		}

	}
    
    /// <summary>
    /// Each profile instance represents a list or a library, the template for the list/library is identified by the Name attribute of the profile instance.
    /// </summary>
    /// <remarks>The profile contains a list of <see cref="SharePoint.ImportExport.Core.Item"/> items</remarks>
	/// <example>
	/// <code>
	/// //Create a new instance of the list class
	/// SharePoint.ImportExport.Core.List list=new List();
	/// 
	/// //Add a new profile node (the profile node indicates to which list/library the data will be imported
	/// Profile profile=new Profile();
	/// list.Profiles.Add(profile);
	/// profile.Name="My Document Library";
	/// 
	/// Item item= new Item();
	/// profile.Items.Add(item);
	/// item.Displayname="My word document.doc";
	/// item.Filename="myworddoc.doc"; //This can also be an absolute or UNC path
	/// 
	/// Itemfield itemField= new Itemfield();
	/// itemField.Name="MyField";
	/// itemField.Type=FieldType.Text;
	/// itemField.Value="My data";
	/// item.Fields.Add(itemField);
	/// 
	/// //Create a new alert
	/// Alert alert= new Alert();
	/// alert.Frequency="Daily";
	/// alert.User="DOMAIN\\user";
	/// alert.Type="Modify";
	/// item.Alerts.Alert.Add(alert);
	/// 
	/// //Create a new portal listing
	/// Categories portalListings=new Categories();
	/// portalListings.Value="//Topics/strategy"; //This are will get the listing
	/// item.Categories.Add(portalListings);
	/// 
	/// try
	///		{
	///			list.Serialize("items.xml");
	///		}
	///	catch(SPExportException ex)
	///		{
	///			Console.WriteLine("Exception occurred: "+ex.Message);
	///		}
	/// </code></example>
	public class Profile 
		{
			/// <summary>
			/// Default constructor of the Profile class
			/// </summary>
			/// <remarks>Instantiates the Item member</remarks>
			public Profile()
			{
				items=new ItemsCollection();
			}
        
        private ItemsCollection items;
			/// <summary>
			/// This is the list of item nodes
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("item", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public ItemsCollection Items
			{
				get
				{
					return items;
				}
			}
        
        /// <summary>
        /// The name member is used for identifying the list/library template.
        /// </summary>
        private string attributename;
		/// <summary>
		/// The name member is used for identifying the list/library template.
		/// </summary>
		[System.Xml.Serialization.XmlAttributeAttribute()]
		public string Name
		{
			get
			{
				return attributename;
			}
			set
			{
				attributename=value;
			}
		}

		/// <summary>
		/// Boolean value that specifies whether the view is hidden.
		/// </summary>
		private bool hidden;
		/// <summary>
		/// Boolean value that specifies whether the view is hidden.
		/// </summary>
		[System.Xml.Serialization.XmlAttributeAttribute("hidden", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
		public bool Hidden
		{
			get
			{
				return hidden;
			}
			set
			{
				hidden=value;
			}
		}
	}
	/// <summary>
	/// This is the class implementing the Items collection <see cref="SharePoint.ImportExport.Core.Item"/>
	/// </summary>
	/// <remarks>
	/// <seealso cref="SharePoint.ImportExport.Core.Item"/><seealso cref="SharePoint.ImportExport.Core.Profile"/>
	/// </remarks>
	public class ItemsCollection:ICollection
	{
		/// <summary>
		/// Default constructor of the ItemsCollection class
		/// </summary>
		/// <remarks>
		/// Instantiates the itemsCollection member</remarks>
		public ItemsCollection()
		{
			itemsCollection=new ArrayList();
		}
		private ArrayList itemsCollection;
		#region ICollection Members

		/// <summary>
		/// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
		/// </summary>
		/// <remarks>
		/// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
		/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
		/// </remarks>
		public bool IsSynchronized
		{
			get
			{
				
				return itemsCollection.IsSynchronized;
			}
		}

		/// <summary>
		/// Returns a value indicating the number of objects in the collection. Read-only.
		/// </summary>
		public int Count
		{
			get
			{
				return itemsCollection.Count;
			}
		}
		/// <summary>
		/// Copies the entire Item array to a compatible one-dimensional Array, starting at the specified index of the target array.
		/// </summary>
		/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
		/// <param name="index">The zero-based index in array at which copying begins</param>
		public void CopyTo(Item[] a, int index)
		{
			itemsCollection.CopyTo(a, index);
		}

		/// <summary>
		/// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
		/// </summary>
		/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
		/// <param name="index">The zero-based index in array at which copying begins</param>
		public void CopyTo(Array a, int index)
		{
			itemsCollection.CopyTo(a, index);
		}

		/// <summary>
		/// Gets an object that can be used to synchronize access to the ArrayList.
		/// </summary>
		/// <remarks>
		/// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
		/// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
		/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
		/// catch the exceptions resulting from changes made by other threads.
		/// </remarks>
		public object SyncRoot
		{
			get
			{
				return itemsCollection.SyncRoot;
			}
		}

		#endregion

		#region IEnumerable Members

		/// <summary>
		/// Returns an enumerator that can iterate through the ArrayList.
		/// </summary>
		/// <returns></returns>
		public IEnumerator GetEnumerator()
		{
			return itemsCollection.GetEnumerator() ;
		}

		#endregion
		/// <summary>
		/// Gets the element at the specified index.
		/// </summary>
		public Item this[int index]
		{
			get{return (Item) itemsCollection[index];}
		}
		/// <summary>
		/// Adds an object to the end of the ArrayList.
		/// </summary>
		/// <param name="newItem">New Item to be added to the list</param>
		public void Add(Item  newItem)
		{
			itemsCollection.Add(newItem);
		}

	}
    
    /// <summary>
    /// This class encapsulates a list item or a document in the document library. This is a member of <see cref="SharePoint.ImportExport.Core.Profile"/>
    /// </summary>
    /// <remarks>
		///		<seealso cref="SharePoint.ImportExport.Core.Profile"/></remarks>
    /// <example>
    /// <code>
		/// //Create a Profile
		/// Item item= new Item();
		/// item.Displayname="My word document.doc";
		/// item.Filename="myworddoc.doc"; //This can also be an absolute or UNC path
		/// 
		/// Itemfield itemField= new Itemfield();
		/// itemField.Name="MyField";
		/// itemField.Type=FieldType.Text;
		/// itemField.Value="My data";
		/// item.Fields.Add(itemField);
		/// 
		/// itemField= new Itemfield("MyUrlField",FieldType.UUL,"http://www.microsoft.com, Microsoft"); //remember the space before the comma
		/// item.Fields.Add(itemField);
		/// 
		/// profile.Items.Add(item);
		/// 
		/// </code>
    /// </example>
    public class Item 
		{
			/// <summary>
			/// Default constructor of the Item class
			/// </summary>
			/// <remarks>Instantiates the Field and Alerts members</remarks>
			public Item()
			{
				fields=new ItemsFieldsCollection();
				alerts = new AlertsCollection();
				categories = new CategoriesCollection();
				attachments = new AttachmentsCollection();
				versions = new VersionsCollection();

			}
			/// <summary>
			/// This is the displayname of the file
			/// </summary>
			private string displayname;
			/// <summary>
			/// This is the displayname of the Attachment
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("displayname",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Displayname
			{
				get
				{
					return displayname;
				}
				set
				{
					displayname=Miscallaneous.FixName(value);
				}
			}
        
			/// <summary>
			/// Tis is the filename of the file in the filesystem
			/// </summary>
			private string filename;

			/// <summary>
			/// This is the filename of the Attachment
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("filename",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Filename
			{
				get
				{
					return filename;
				}
				set
				{
					filename=value;
				}
			}
		
			/// <summary>
			/// This is the name of the person for the audit history
			/// </summary>
			private string owner;
			/// <summary>
			/// This is the name of the person who performed the versioning. Used for auditing purposes
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("owner",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Owner
			{
				get
				{
					return owner;
				}
				set
				{
					owner=value;
				}
			}
			private string description;
			/// <summary>
			/// This is the description of the file
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("description",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Description
			{
				get
				{
					return description;
				}
				set
				{
					description=value;
				}
			}

			private string comment;
			/// <summary>
			/// This is the comment for the audit history
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("comment",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Comment
			{
				get
				{
					return comment;
				}
				set
				{
					comment=value;
				}
			}

			private string version;
			/// <summary>
			/// This is the version information of the document
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("version",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Version
			{
				get
				{
					return version;
				}
				set
				{
					version=value;
				}
			}


        private ItemsFieldsCollection fields;
			/// <summary>
			/// This is a collection of metadata fields
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("field", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public ItemsFieldsCollection Fields
			{
				get
				{
					return fields;
				}
			}
        

			private AttachmentsCollection attachments;
			/// <summary>
			/// This is a collection of attachments. Only valid for lists
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("attachment", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public AttachmentsCollection Attachments
			{
				get
				{
					return attachments;
				}
			}
        
        private CategoriesCollection categories;
			/// <summary>
			/// This is a list of the portal areas that will get portal listings to the item
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("categories", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public CategoriesCollection Categories
			{
				get 
				{
					return categories;
				}
			}
        
			private AlertsCollection alerts;

				/// <summary>
				/// This is a list of the alerts that will be created
				/// </summary>
			[System.Xml.Serialization.XmlArray("alerts", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			[System.Xml.Serialization.XmlArrayItem("alert", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public AlertsCollection Alerts
			{
				get
				{
					return alerts;
				}
			}
			private VersionsCollection versions;

				/// <summary>
				/// This is a list of the versions that will be created. See <see cref="SharePoint.ImportExport.Core.VersionsCollection"/>
				/// </summary>
				/// <example>
				/// <code>				
				/// Item itemV= new Item();
				/// item.Versions.Add(itemV);
				/// itemV.Owner="Kimmo Forss";
				/// itemV.Displayname="My word document.doc";
				/// itemV.Filename="myworddoc2.doc"; //This can also be an absolute or UNC path
				/// 	</code></example>
			[System.Xml.Serialization.XmlArray("versions", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			[System.Xml.Serialization.XmlArrayItem("item", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public VersionsCollection Versions
			{
				get
				{
					return versions;
				}
			}

			private int id=0;

			/// <summary>
			/// This is the ID of the listitem
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("id",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public int ID
			{
				get
				{
					return id;
				}
				set
				{
					id=value;
				}
			}


    }
	/// <summary>
	/// This is the class implementing the ItemFields collection <see cref="SharePoint.ImportExport.Core.Itemfield"/>
	/// </summary>
	/// <seealso cref="SharePoint.ImportExport.Core.Itemfield"/><seealso cref="SharePoint.ImportExport.Core.Item"/>
	public class ItemsFieldsCollection:ICollection
		{
		/// <summary>
		/// This is the default constructor for the ItemsFieldsCollection class
		/// </summary>
		/// <remarks>Instantiates the itemsFieldsCollection member</remarks>
			public ItemsFieldsCollection()
			{
				itemsFieldsCollection=new ArrayList();
			}
			private ArrayList itemsFieldsCollection;
			#region ICollection Members

		/// <summary>
		/// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
		/// </summary>
		/// <remarks>
		/// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
		/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
		/// </remarks>
		public bool IsSynchronized
			{
				get
				{
				
					return itemsFieldsCollection.IsSynchronized;
				}
			}
			/// <summary>
			/// Returns a value indicating the number of objects in the collection. Read-only.
			/// </summary>
			public int Count
			{
				get
				{
					return itemsFieldsCollection.Count;
				}
			}
		/// <summary>
		/// Copies the entire ItemField Array to a compatible one-dimensional Array, starting at the specified index of the target array.
		/// </summary>
		/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
		/// <param name="index">The zero-based index in array at which copying begins</param>
		public void CopyTo(Itemfield[] a, int index)
		{
			itemsFieldsCollection.CopyTo(a, index);
		}


		/// <summary>
		/// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
		/// </summary>
		/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
		/// <param name="index">The zero-based index in array at which copying begins</param>
		public void CopyTo(Array a, int index)
			{
				itemsFieldsCollection.CopyTo(a, index);
			}

		/// <summary>
		/// Gets an object that can be used to synchronize access to the ArrayList.
		/// </summary>
		/// <remarks>
		/// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
		/// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
		/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
		/// catch the exceptions resulting from changes made by other threads.
		/// </remarks>
		public object SyncRoot
			{
				get
				{
					return itemsFieldsCollection.SyncRoot;
				}
			}

			#endregion

			#region IEnumerable Members

		/// <summary>
		/// Returns an enumerator that can iterate through the ArrayList.
		/// </summary>
		/// <returns></returns>
		public IEnumerator GetEnumerator()
			{
				return itemsFieldsCollection.GetEnumerator() ;
			}

			#endregion
		/// <summary>
		/// Gets the element at the specified index.
		/// </summary>
		public Itemfield this[int index]
			{
				get{return (Itemfield) itemsFieldsCollection[index];}
			}
		/// <summary>
		/// Adds an object to the end of the ArrayList.
		/// </summary>
		/// <param name="newItemField">New ItemField to be added to the list</param>
			public void Add(Itemfield  newItemField)
			{
				itemsFieldsCollection.Add(newItemField);
			}

		}
 
    /// <summary>
    /// This is the class encapsulating the meta data 
    /// </summary>
    public class Itemfield 
		
		{
			/// <summary>
			/// Default Constructor
			/// </summary>
			public Itemfield()
			{
			}
			/// <summary>
			/// Constructor that sets the values
			/// </summary>
			/// <param name="fieldName">Name of the field</param>
			/// <param name="fieldType">Datatype of the field</param>
			/// <param name="fieldValue">Value of the field</param>
			public Itemfield(string fieldName,FieldType fieldType,string fieldValue)
			{
				name=fieldName;
				type=fieldType;
				fieldvalue=fieldValue;
			}
			private string name;
				/// <summary>
				/// This is the name of the metadata field
				/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("name", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Name
				{
					get
					{
						return name;
					}
					set
					{
						name=value;
					}
				}
        
        /// <summary>
        /// This is the field type
        /// </summary>
        private FieldType type;
				/// <summary>
				/// This is the datatype of the metadata field
				/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("type", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public FieldType Type
				{
					get
					{
						return type;
					}
					set
					{
						type=value;
					}
				}
        
        /// <summary>
        /// This is the actual field value
        /// </summary>
        private string fieldvalue;
			/// <summary>
			/// This is the datavalue of the metadata field
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("value", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Value
			{
				get
				{
					return fieldvalue;
				}
				set
				{
					fieldvalue=value;
				}
			}


    }
    
	/// <summary>
	/// This is the class implementing the Categories collection
	/// </summary>
	public class CategoriesCollection:ICollection
	{
		/// <summary>
		/// This is the default constructor for the CategoriesCollection class
		/// </summary>
		/// <remarks>Instantiates the categories member</remarks>
		public CategoriesCollection()
		{
			categories=new ArrayList();
		}
		private ArrayList categories;
		#region ICollection Members

		/// <summary>
		/// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
		/// </summary>
		/// <remarks>
		/// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
		/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
		/// </remarks>
		public bool IsSynchronized
		{
			get
			{
				
				return categories.IsSynchronized;
			}
		}
		/// <summary>
		/// Returns a value indicating the number of objects in the collection. Read-only.
		/// </summary>
		public int Count
		{
			get
			{
				return categories.Count;
			}
		}
		/// <summary>
		/// Copies the entire Category Array to a compatible one-dimensional Array, starting at the specified index of the target array.
		/// </summary>
		/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
		/// <param name="index">The zero-based index in array at which copying begins</param>
		public void CopyTo(Category[] a, int index)
		{
			categories.CopyTo(a, index);
		}


		/// <summary>
		/// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
		/// </summary>
		/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
		/// <param name="index">The zero-based index in array at which copying begins</param>
		public void CopyTo(Array a, int index)
		{
			categories.CopyTo(a, index);
		}

		/// <summary>
		/// Gets an object that can be used to synchronize access to the ArrayList.
		/// </summary>
		/// <remarks>
		/// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
		/// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
		/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
		/// catch the exceptions resulting from changes made by other threads.
		/// </remarks>
		public object SyncRoot
		{
			get
			{
				return categories.SyncRoot;
			}
		}

		#endregion

		#region IEnumerable Members

		/// <summary>
		/// Returns an enumerator that can iterate through the ArrayList.
		/// </summary>
		/// <returns></returns>
		public IEnumerator GetEnumerator()
		{
			return categories.GetEnumerator() ;
		}

		#endregion
		/// <summary>
		/// Gets the element at the specified index.
		/// </summary>
		public Category this[int index]
		{
			get{return (Category) categories[index];}
		}
		/// <summary>
		/// Adds an object to the end of the ArrayList.
		/// </summary>
		/// <param name="newCategory">New Categories to be added to the list</param>
		public void Add(Category  newCategory)
		{
			categories.Add(newCategory);
		}

	}

    /// <summary>
    /// This class encapsulates all the portal listings that will be created
    /// </summary>
    /// <example>
    /// <code>
		/// //Create a new portal listing
		/// Categories portalListings=new Categories();
		/// portalListings.Value="//Topics/strategy";
		/// item.Categories.Add(portalListings);
		/// </code></example>
    public class Category 
		{
        
        /// <summary>
        /// This is the relative Url to the topic area that will get the listing
        /// </summary>
        /// <example>Topics/Divisions</example>
        private string categoryValue;

			/// <summary>
			/// This is the relative Url to the topic area that will get the listing
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("value",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string Value
			{
				get
				{
					return categoryValue;
				}
				set
				{
					categoryValue=value;
				}
			}
			/// <summary>
			/// This is the default empty constructor
			/// </summary>
			public Category()
			{
			}
			/// <summary>
			/// This is the constructor that accepts the value as a parameter
			/// </summary>
			/// <param name="category">This is the relative Url to the topic area that will get the listing</param>
			public Category(string category)
			{
				categoryValue=category;
			}
    }
	/// <summary>
	/// This is the class implementing the ItemFields collection <see cref="SharePoint.ImportExport.Core.Itemfield"/>
	/// </summary>
	/// <seealso cref="SharePoint.ImportExport.Core.Attachment"/><seealso cref="SharePoint.ImportExport.Core.Item"/>
	public class AttachmentsCollection:ICollection
	{
		/// <summary>
		/// This is the default constructor for the ItemsFieldsCollection class
		/// </summary>
		/// <remarks>Instantiates the itemsFieldsCollection member</remarks>
		public AttachmentsCollection()
		{
			attachmentsCollection=new ArrayList();
		}
		private ArrayList attachmentsCollection;
		#region ICollection Members

		/// <summary>
		/// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
		/// </summary>
		/// <remarks>
		/// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
		/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
		/// </remarks>
		public bool IsSynchronized
		{
			get
			{
				
				return attachmentsCollection.IsSynchronized;
			}
		}
		/// <summary>
		/// Returns a value indicating the number of objects in the collection. Read-only.
		/// </summary>
		public int Count
		{
			get
			{
				return attachmentsCollection.Count;
			}
		}
		/// <summary>
		/// Copies the entire Attachment Array to a compatible one-dimensional Array, starting at the specified index of the target array.
		/// </summary>
		/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
		/// <param name="index">The zero-based index in array at which copying begins</param>
		public void CopyTo(Attachment[] a, int index)
		{
			attachmentsCollection.CopyTo(a, index);
		}


		/// <summary>
		/// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
		/// </summary>
		/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
		/// <param name="index">The zero-based index in array at which copying begins</param>
		public void CopyTo(Array a, int index)
		{
			attachmentsCollection.CopyTo(a, index);
		}

		/// <summary>
		/// Gets an object that can be used to synchronize access to the ArrayList.
		/// </summary>
		/// <remarks>
		/// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
		/// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
		/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
		/// catch the exceptions resulting from changes made by other threads.
		/// </remarks>
		public object SyncRoot
		{
			get
			{
				return attachmentsCollection.SyncRoot;
			}
		}

		#endregion

		#region IEnumerable Members

		/// <summary>
		/// Returns an enumerator that can iterate through the ArrayList.
		/// </summary>
		/// <returns></returns>
		public IEnumerator GetEnumerator()
		{
			return attachmentsCollection.GetEnumerator() ;
		}

		#endregion
		/// <summary>
		/// Gets the element at the specified index.
		/// </summary>
		public Attachment this[int index]
		{
			get{return (Attachment) attachmentsCollection[index];}
		}
		/// <summary>
		/// Adds an object to the end of the ArrayList.
		/// </summary>
		/// <param name="newAttachment">New Attachment to be added to the list</param>
		public void Add(Attachment  newAttachment)
		{
			attachmentsCollection.Add(newAttachment);
		}

	}
 
    
    /// <summary>
    /// This is the class encapsulating the attachment
    /// </summary>
    /// <example>
    /// <code>
    /// Attachment attachment=new Attachment();
		/// attachment.DisplayName="Invitation.doc";
		/// attachment.FileName="Invitation.doc";
		/// item.Attachments.Add(attachment);
    /// </code>
    /// </example>
    /// <remarks><seealso cref="SharePoint.ImportExport.Core.DataContainer"/> and <seealso cref="SharePoint.ImportExport.Core.Item"/></remarks>
    public class Attachment 
		{
        
        /// <summary>
        /// This is the displayname of the attachment
        /// </summary>
        private string displayname;
        

			/// <summary>
			/// This is the displayname of the Attachment
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("displayname",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string DisplayName
			{
				get
				{
					return displayname;
				}
				set
				{
					displayname=Miscallaneous.FixName(value);;
				}
			}
			/// <summary>
			/// This is the filename of the file in the filesystem
			/// </summary>
			private string filename;
			/// <summary>
			/// This is the filename of the Attachment
			/// </summary>
			[System.Xml.Serialization.XmlElementAttribute("filename",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
			public string FileName
			{
				get
				{
					return filename;
				}
				set
				{
					filename=value;
				}
			}
			/// <summary>
			/// This is the default empty constructor
			/// </summary>
			public Attachment()
			{
			}
			/// <summary>
			/// This is the constructor with parameters
			/// </summary>
			/// <param name="displayName">This is the display name of the attachment</param>
			/// <param name="fileName">This is the filename of the attachment</param>
			public Attachment(string displayName, string fileName)
			{
				displayname=displayName;
				filename=fileName;
			}
		}
	/// <summary>
	/// This is the class implementing the Versions collection
	/// </summary>
	/// <remarks>This class is used to add version of existing files. Note that the filename for each item added here must be the same that this item has
	///<example>
	///<code>
	/// //Create the first item before adding versions
	///	Item versionItem= new Item();
	///	item.Versions.Add(versionItem);
	///	versionItem.Displayname="My word document.doc"; //Must be the same as item.DisplayName
	///	versionItem.Filename="myworddoc2.doc"; //This can also be an absolute or UNC path
	///	versionItem.Owner="Joe User";
	///	versionItem.Comment="Audit history comments";
	///</code>
	///</example>
	///</remarks>
	public class VersionsCollection:ICollection
	{
		/// <summary>
		/// This is the default constructor for the CategoriesCollection class
		/// </summary>
		/// <remarks>Instantiates the categories member</remarks>
		public VersionsCollection()
		{
			versionsCollection=new ArrayList();
		}
		private ArrayList versionsCollection;
		#region ICollection Members

		/// <summary>
		/// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
		/// </summary>
		/// <remarks>
		/// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
		/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
		/// </remarks>
		public bool IsSynchronized
		{
			get
			{
				
				return versionsCollection.IsSynchronized;
			}
		}
		/// <summary>
		/// Returns a value indicating the number of objects in the collection. Read-only.
		/// </summary>
		public int Count
		{
			get
			{
				return versionsCollection.Count;
			}
		}
		/// <summary>
		/// Copies the entire Version Array to a compatible one-dimensional Array, starting at the specified index of the target array.
		/// </summary>
		/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
		/// <param name="index">The zero-based index in array at which copying begins</param>
		public void CopyTo(Item[] a, int index)
		{
			versionsCollection.CopyTo(a, index);
		}


		/// <summary>
		/// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
		/// </summary>
		/// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
		/// <param name="index">The zero-based index in array at which copying begins</param>
		public void CopyTo(Array a, int index)
		{
			versionsCollection.CopyTo(a, index);
		}

		/// <summary>
		/// Gets an object that can be used to synchronize access to the ArrayList.
		/// </summary>
		/// <remarks>
		/// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
		/// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
		/// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
		/// catch the exceptions resulting from changes made by other threads.
		/// </remarks>
		public object SyncRoot
		{
			get
			{
				return versionsCollection.SyncRoot;
			}
		}

		#endregion

		#region IEnumerable Members

		/// <summary>
		/// Returns an enumerator that can iterate through the ArrayList.
		/// </summary>
		/// <returns></returns>
		public IEnumerator GetEnumerator()
		{
			return versionsCollection.GetEnumerator() ;
		}

		#endregion
		/// <summary>
		/// Gets the element at the specified index.
		/// </summary>
		public Item this[int index]
		{
			get{return (Item) versionsCollection[index];}
		}
		/// <summary>
		/// Adds an object to the end of the ArrayList.
		/// </summary>
		/// <param name="newItem">New Item to be added to the list</param>
		public void Add(Item  newItem)
		{
			versionsCollection.Add(newItem);
		}

	}

}
